// CODE128.js - 已改为 ES Module 格式，兼容 UniApp

import Barcode from '../Barcode.js'; // 确保路径正确
import { 
  SET_A, SET_B, SET_C, 
  FNC1, MODULO, STOP, 
  SET_BY_CODE, SWAP, BARS 
} from './constants.js';

// CODE128 编码主类
class CODE128 extends Barcode {
  constructor(data, options) {
    super(data.substring(1), options); // 去掉起始符后的数据

    // 将字符串转换为 ASCII 码数组
    this.bytes = data.split('').map(char => char.charCodeAt(0));
  }

  // 验证输入数据是否合法
  valid() {
    // 支持 ASCII 0-127 和 CODE128 控制字符 200-211
    return /^[\x00-\x7F\xC8-\xD3]+$/.test(this.data);
  }

  // 判断是否为 GS1-128/EAN-128 条码
  shouldEncodeAsEan128() {
    const isEAN128 = this.options.ean128 || false;
    if (typeof isEAN128 === 'string') {
      return isEAN128.toLowerCase() === 'true';
    }
    return Boolean(isEAN128);
  }

  // 编码主函数
  encode() {
    let bytes = [...this.bytes]; // 避免修改原数组
    const startIndex = bytes.shift() - 105; // 获取起始码索引
    const startSet = SET_BY_CODE[startIndex];

    if (startSet === undefined) {
      throw new RangeError('编码必须以起始字符开始（CODE128A/B/C 对应 ASCII 200/201/202）');
    }

    // 如果是 EAN-128，插入 FNC1
    if (this.shouldEncodeAsEan128()) {
      bytes.unshift(FNC1);
    }

    // 开始递归编码
    const encodingResult = CODE128.next(bytes, 1, startSet);

    // 构建最终条码数据
    const resultData = 
      CODE128.getBar(startIndex) +           // 起始符
      encodingResult.result +                // 编码内容
      CODE128.getBar((encodingResult.checksum + startIndex) % MODULO) + // 校验和
      CODE128.getBar(STOP);                  // 终止符

    return {
      data: resultData,
      text: this.text === this.data 
        ? this.text.replace(/[^\x20-\x7E]/g, '') // 清理不可打印字符
        : this.text
    };
  }

  // 静态方法：根据索引获取条码二进制表示
  static getBar(index) {
    return BARS[index] ? BARS[index].toString() : '';
  }

  // 静态方法：根据字符集正确解析字符索引
  static correctIndex(bytes, set) {
    if (set === SET_A) {
      const charCode = bytes.shift();
      return charCode < 32 ? charCode + 64 : charCode - 32;
    } else if (set === SET_B) {
      return bytes.shift() - 32;
    } else if (set === SET_C) {
      return (bytes.shift() - 48) * 10 + (bytes.shift() - 48);
    }
  }

  // 静态方法：递归编码核心逻辑
  static next(bytes, pos, set) {
    if (!bytes.length) {
      return { result: '', checksum: 0 };
    }

    let index;
    let nextResult;

    // 处理特殊控制字符（FNC1-FNC4, SHIFT, CODE_A/B/C, STOP）
    if (bytes[0] >= 200) {
      index = bytes[0] - 105;
      const nextSet = SWAP[index];

      if (nextSet !== undefined) {
        // 切换字符集（如 CODE_A -> CODE_B）
        bytes.shift();
        nextResult = CODE128.next(bytes, pos + 1, nextSet);
      } else {
        // 特殊功能字符（如 SHIFT）
        if ((set === SET_A || set === SET_B) && index === 28) { // SHIFT
          bytes.shift();
          if (bytes.length > 0) {
            // 临时转换下一个字符
            if (set === SET_A) {
              bytes[0] = bytes[0] > 95 ? bytes[0] - 96 : bytes[0];
            } else {
              bytes[0] = bytes[0] < 32 ? bytes[0] + 96 : bytes[0];
            }
          }
        } else {
          bytes.shift(); // 其他特殊字符直接跳过
        }
        nextResult = CODE128.next(bytes, pos + 1, set);
      }
    } else {
      // 普通字符编码
      index = CODE128.correctIndex(bytes, set);
      nextResult = CODE128.next(bytes, pos + 1, set);
    }

    // 获取当前字符的条码表示并计算权重
    const bar = CODE128.getBar(index);
    const weight = index * pos;

    return {
      result: bar + nextResult.result,
      checksum: weight + nextResult.checksum
    };
  }
}

// 默认导出
export default CODE128;